 #include "mylistwidgetitem.h"
#include "ui_mylistwidgetitem.h"
#include "publicstruct.h"
#include "mytcpsocket.h"

#include <QFileDialog>


MyListWidgetItem::MyListWidgetItem(const QString& content,int flag,QPixmap head,int type,QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyListWidgetItem)
{
    ui->setupUi(this);


    m_data = content;
    m_flag = flag;
    head_pixmap = head;
    msg_type = type;

    this->curr_Width = this->width();
    this->curr_height = this->height();

    if(msg_type == 52){
        m_file = QPixmap(":/prefix2/software/TXT.png");
        QStringList ml = m_data.split('#');
        // 获取文件ID
        fileID = ml.back();
        QStringList ml2 = ml.front().split('/');
        m_fname = ml2.back();
        long fsize = ml.at(1).toLong();
        // 1B ~ 1023B
        if(fsize < 1024){
            m_fsize = QString("%1%2").arg(fsize).arg("B");
        }
        // 1KB ~ 1023KB
        else if(fsize >= 1024 && fsize < 1048576){
            m_fsize = QString("%1%2").arg(fsize/1024).arg("KB");
        }
        // 1MB ~ 1023MB
        else if(fsize >= 1048576 && fsize < 1073741824){
            m_fsize = QString("%1%2").arg(fsize/1024/1024).arg("MB");
        }
        // 1GB ~ ...
        else if(fsize >= 1073741824){
            m_fsize = QString("%1%2").arg(fsize/1024/1024/1024).arg("GB");
        }
    }

    if(msg_type == 53 || msg_type == 55){
        QString srvpath = QString("%1/%2").arg(PATH_JOY).arg(m_data);
        m_joy = PixmapToRoundOpenCV(downLoadFromUrl(srvpath));    //当类型为表情时,m_data存储的是服务器上表情的路径
    }

    this->installEventFilter(this);

}

MyListWidgetItem::~MyListWidgetItem()
{
    delete ui;
}

void MyListWidgetItem::paintEvent(QPaintEvent* event){
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform); //抗锯齿

    //私/群聊文字
    if(msg_type == 51 || msg_type == 54){
        int head_wh = 40;                   //头像的宽高
        int head_HoriSpace_window = 15;     //头像与窗口的水平距离
        int head_VertSpace_window = 5;      //头像与窗口的垂直距离
        int head_HoriSpace_bubble = 15;     //头像与气泡的水平距离
        int text_HoriSpace_bubble = 10;     //文本与气泡的水平距离
        int text_VertSpace_bubble = 5;      //文本与气泡的垂直距离
        int bubble_Vert_window = 10;        //气泡与窗口的垂直距离
        //规定文本基于当前窗口的最大宽度,若消息的长度大于这个宽度,就要换行显示
        //文本最大宽度 = 当前窗口宽度 - 2*(头像与窗口的水平距离+头像的宽度+头像和气泡的水平距离+文本和气泡的间距)
        int Max_Width = curr_Width - 2*(head_HoriSpace_window+head_wh+head_HoriSpace_bubble+text_HoriSpace_bubble);

        QFont font("楷体",15);
        this->setFont(font);
        QFontMetrics fontMetrics = this->fontMetrics(); //返回部件字体指标

        if(m_flag == R_FRIEND){   //好友 左侧
            //头像
            Rect_Lefthead = QRect(QPoint(head_HoriSpace_window,head_VertSpace_window),QSize(head_wh,head_wh));  //头像位置
            painter.drawPixmap(Rect_Lefthead,head_pixmap); //画头像

            //气泡
            painter.setPen(Qt::black);
            painter.setBrush(QColor(235,235,235));  //气泡颜色
            Rect_LeftBubble = fontMetrics.boundingRect(m_data); //根据文本返回一个矩形(返回墨迹覆盖的矩形)

            int temp_width = Rect_LeftBubble.width();   //文本的宽
            int temp_height = Rect_LeftBubble.height();   //文本的宽

            //在文本矩形的基础上,画一个更大的矩形,就是气泡
    //        Rect_LeftBubble = QRect(QPoint(head_wh + head_HoriSpace_bubble + head_HoriSpace_window,bubble_Vert_window),
    //                        QSize(Rect_LeftBubble.width()+2*text_HoriSpace_bubble,Rect_LeftBubble.height()+2*text_VertSpace_bubble));

            if(temp_width>Max_Width)   //如果文本矩形的宽大于最大宽度,那么就计算需要多少个换行显示
            {
                //需要的换行数
                int n_num = temp_width/Max_Width;
                //根据换行数计算需要多少行才能存放全部内容
                int rows = n_num + 1;   //行数决定新矩形的高度
                //计算新的气泡矩形的大小
                int nex_w = Max_Width + 2*text_HoriSpace_bubble;                //新气泡的宽
                int new_h = rows*temp_height+2*text_VertSpace_bubble;            //新气泡的高
                int new_x = head_HoriSpace_window+head_wh+head_HoriSpace_bubble;   //新气泡的x坐标
                int new_y = bubble_Vert_window;                                 //新气泡的y坐标

                //新气泡矩形:   在文本矩形的基础上,画一个更大的矩形,就是气泡
                QRect NewRect = QRect(QPoint(new_x,new_y),QSize(nex_w,new_h)); //将新的高度回传给主界面更新QListWidgetItem的高度

                //传回主界面更新的高度,要多传2倍的气泡与窗口的高度,这样气泡才会在中间,不会贴边边
                emit sig_rectChange(QSize(Max_Width,new_h+2*bubble_Vert_window),seq);

                //绘制圆角矩形
                painter.drawRoundedRect(NewRect,4,4);

                //文字
                painter.drawText(QRect(NewRect.x()+text_HoriSpace_bubble,NewRect.y()+text_VertSpace_bubble,
                                       Max_Width,NewRect.height()-2*text_VertSpace_bubble),m_data);
            }
            else{   //单行
                int nex_w = temp_width + 2*text_HoriSpace_bubble;                   //新气泡的宽
                int new_h = temp_height + 2*text_VertSpace_bubble;                  //新气泡的高
                int new_x = head_HoriSpace_window + head_wh + head_HoriSpace_bubble;   //新气泡的x坐标
                int new_y = bubble_Vert_window;                                     //新气泡的y坐标

                //新气泡矩形:   在文本矩形的基础上,画一个更大的矩形,就是气泡
                QRect NewRect = QRect(QPoint(new_x,new_y),QSize(nex_w,new_h));

                //绘制圆角矩形
                painter.drawRoundedRect(NewRect,4,4);

                //文字
                painter.drawText(QRect(NewRect.x()+text_HoriSpace_bubble,NewRect.y()+text_VertSpace_bubble,
                                       nex_w,temp_height),m_data);
            }
        }
        else{  //用户 右侧
            //头像  x:窗口宽-头像与窗口水平间距-头像宽  y:头像与窗口垂直间距
            Rect_Righthead = QRect(QPoint(curr_Width - head_wh - head_HoriSpace_window,head_VertSpace_window),QSize(head_wh,head_wh));
            painter.drawPixmap(Rect_Righthead,head_pixmap);

            //气泡  x:头像与窗口水平间距+头像宽+头像与气泡的水平间距 y:气泡与窗口垂直间距
            painter.setPen(Qt::white);
            painter.setBrush(QColor(75,164,241));   //气泡颜色
            Rect_RightBubble = fontMetrics.boundingRect(m_data);    //根据文本返回覆盖墨迹的矩形

            int temp_width = Rect_RightBubble.width();  //文本的宽
            int temp_height = Rect_RightBubble.height(); //文本的高

            if(temp_width>Max_Width)   //如果文本矩形宽度大于最大宽度,那么就计算需要多少个换行显示
            {
                //int max_ch = fontMetrics.maxWidth(); //当前字体最大字符的宽度
                //int max_row_num = Max_Width/max_ch;  //每一行最大的字符数

                //需要的换行数
                int n_num = temp_width/Max_Width;
                //根据换行数计算需要多少行才能存放全部内容
                int rows = n_num + 1;   //行数决定新矩形的高度
                //计算新的气泡矩形的大小
                int nex_w = Max_Width + 2*text_HoriSpace_bubble;                //新气泡的宽
                int new_h = rows*temp_height+2*text_VertSpace_bubble;            //新气泡的高
                int new_x = head_HoriSpace_window+head_wh+head_HoriSpace_bubble;   //新气泡的x坐标
                int new_y = bubble_Vert_window;                                 //新气泡的y坐标

                //新气泡矩形:   在文本矩形的基础上,画一个更大的矩形,就是气泡
                QRect NewRect = QRect(QPoint(new_x,new_y),QSize(nex_w,new_h)); //将新的高度回传给主界面更新QListWidgetItem的高度

                //传回主界面更新的高度,要多传2倍的气泡与窗口的高度,这样气泡才会在中间,不会贴边边
                emit sig_rectChange(QSize(Max_Width,new_h+2*bubble_Vert_window),seq);

                //绘制圆角矩形
                painter.drawRoundedRect(NewRect,4,4);

                //文字
                painter.drawText(QRect(NewRect.x()+text_HoriSpace_bubble,NewRect.y()+text_VertSpace_bubble,
                                       Max_Width,NewRect.height()-2*text_VertSpace_bubble),m_data);

            }
            else{   //单行
                int nex_w = temp_width + 2*text_HoriSpace_bubble;                //新气泡的宽
                int new_h = temp_height + 2*text_VertSpace_bubble;              //新气泡的高
                int new_x = curr_Width - head_HoriSpace_window - head_wh - head_HoriSpace_bubble - nex_w;   //新气泡的x坐标
                int new_y = bubble_Vert_window;                                     //新气泡的y坐标


                //新气泡矩形:   在文本矩形的基础上,画一个更大的矩形,就是气泡
                QRect NewRect = QRect(QPoint(new_x,new_y),QSize(nex_w,new_h));

                //绘制圆角矩形
                painter.drawRoundedRect(NewRect,4,4);

                //文字
                painter.drawText(QRect(NewRect.x()+text_HoriSpace_bubble,NewRect.y()+text_VertSpace_bubble,
                                       nex_w,temp_height),m_data);
            }
        }
    }
    // 私聊文件
    else if(msg_type == 52){
        int head_wh = 40;                   //头像的宽高
        int head_HoriSpace_window = 15;     //头像与窗口的水平距离
        int head_VertSpace_window = 5;      //头像与窗口的垂直距离
        int head_HoriSpace_bubble = 15;     //头像与气泡的水平距离
        int fdata_HoriSpace_bubble = 10;     //文件信息与气泡的水平距离
        int fdata_VertSpace_bubble = 3;      // 文件信息与气泡的垂直距离
        int bubble_Vert_window = 10;        //气泡与窗口的垂直距离
        int fdata_HoriSpace_icon = 10;    // 文件信息与文件图标的水平距离
        int icon_Vert_bubble = 5;        // 文件图标与气泡的垂直距离

        QFont font("楷体",9);
        this->setFont(font);
        QFontMetrics fontMetrics = this->fontMetrics(); //返回部件字体指标

        QRect tmp_rect = fontMetrics.boundingRect(m_fname); //根据文件名返回一个矩形(返回墨迹覆盖的矩形)
        // 用户 右侧
        if(m_flag == R_USER){
            //头像  x:窗口宽-头像与窗口水平间距-头像宽  y:头像与窗口垂直间距
            Rect_Righthead = QRect(QPoint(curr_Width - head_wh - head_HoriSpace_window,head_VertSpace_window),QSize(head_wh,head_wh));
            painter.drawPixmap(Rect_Righthead,head_pixmap);

            painter.setPen(Qt::white);
            painter.setBrush(QColor(75,164,241));   //气泡颜色

            int temp_width = 23;  //文件的宽
            int temp_height = 23; //文件的高
            int data_width = tmp_rect.width();   // 文件信息的宽
            int data_height = tmp_rect.height();   // 文件信息的高

            int nex_w = temp_width + 2*fdata_HoriSpace_bubble + data_width + fdata_HoriSpace_icon;             //新气泡的宽
            int new_h = temp_height + 2*icon_Vert_bubble;            //新气泡的高
            int new_x = curr_Width - head_HoriSpace_window - head_wh - head_HoriSpace_bubble - nex_w;   //新气泡的x坐标
            int new_y = bubble_Vert_window;                                     //新气泡的y坐标

            //新气泡矩形:   在文本矩形的基础上,画一个更大的矩形,就是气泡
            QRect NewRect = QRect(QPoint(new_x,new_y),QSize(nex_w,new_h));

            //绘制圆角矩形
            painter.drawRoundedRect(NewRect,4,4);

            //绘制文件图标
            painter.drawPixmap(QRect(NewRect.x()+fdata_HoriSpace_bubble,NewRect.y()+icon_Vert_bubble,
                                    temp_width,temp_height),m_file);

            //绘制文件信息
            // 文件名矩形
            int fname_x = NewRect.x()+fdata_HoriSpace_bubble+temp_width+fdata_HoriSpace_icon;
            int fname_y = bubble_Vert_window + fdata_VertSpace_bubble;
            QRect fnameRect = QRect(fname_x,fname_y,data_width,data_height);
            // 文件大小矩形
            int fsize_x = fnameRect.x();
            int fsize_y = fnameRect.y() + fnameRect.height();
            QRect fsizeRect = QRect(fsize_x,fsize_y,data_width,data_height);
            painter.drawText(fnameRect,m_fname);
            painter.drawText(fsizeRect,m_fsize);
        }
        // 好友 左侧
        else{
            //头像  x:窗口与头像的水平距离  y:头像与窗口垂直间距
            Rect_Righthead = QRect(QPoint(head_HoriSpace_window,head_VertSpace_window),QSize(head_wh,head_wh));
            painter.drawPixmap(Rect_Righthead,head_pixmap);

            painter.setPen(Qt::black);
            painter.setBrush(QColor(235,235,235));  //气泡颜色

            int temp_width = 23;  //文件的宽
            int temp_height = 23; //文件的高
            int data_width = tmp_rect.width();   // 文件信息的宽
            int data_height = tmp_rect.height();   // 文件信息的高

            int nex_w = temp_width + 2*fdata_HoriSpace_bubble + data_width + fdata_HoriSpace_icon;             //新气泡的宽
            int new_h = temp_height + 2*icon_Vert_bubble;            //新气泡的高
            int new_x = head_HoriSpace_window + head_wh + head_HoriSpace_bubble;   //新气泡的x坐标
            int new_y = bubble_Vert_window;                                     //新气泡的y坐标

            //新气泡矩形:   在文本矩形的基础上,画一个更大的矩形,就是气泡
            QRect NewRect = QRect(QPoint(new_x,new_y),QSize(nex_w,new_h));

            //绘制圆角矩形
            painter.drawRoundedRect(NewRect,4,4);

            //绘制文件图标
            painter.drawPixmap(QRect(NewRect.x()+fdata_HoriSpace_bubble,NewRect.y()+icon_Vert_bubble,
                                    temp_width,temp_height),m_file);

            //绘制文件信息
            // 文件名矩形
            int fname_x = NewRect.x()+fdata_HoriSpace_bubble+temp_width+fdata_HoriSpace_icon;
            int fname_y = bubble_Vert_window + fdata_VertSpace_bubble;
            QRect fnameRect = QRect(fname_x,fname_y,data_width,data_height);
            // 文件大小矩形
            int fsize_x = fnameRect.x();
            int fsize_y = fnameRect.y() + fnameRect.height();
            QRect fsizeRect = QRect(fsize_x,fsize_y,data_width,data_height);
            painter.drawText(fnameRect,m_fname);
            painter.drawText(fsizeRect,m_fsize);

        }
    }
    // 私/群聊表情
    else if(msg_type == 53 || msg_type == 55){
        int head_wh = 40;                   //头像的宽高
        int head_HoriSpace_window = 15;     //头像与窗口的水平距离
        int head_VertSpace_window = 5;      //头像与窗口的垂直距离
        int head_HoriSpace_bubble = 15;     //头像与气泡的水平距离
        int joy_HoriSpace_bubble = 10;     //表情与气泡的水平距离
        int joy_VertSpace_bubble = 5;      //表情与气泡的垂直距离
        int bubble_Vert_window = 10;        //气泡与窗口的垂直距离


        //用户 右侧
        if(m_flag == R_USER){
            //头像  x:窗口宽-头像与窗口水平间距-头像宽  y:头像与窗口垂直间距
            Rect_Righthead = QRect(QPoint(curr_Width - head_wh - head_HoriSpace_window,head_VertSpace_window),QSize(head_wh,head_wh));
            painter.drawPixmap(Rect_Righthead,head_pixmap);

            painter.setPen(Qt::white);
            painter.setBrush(QColor(75,164,241));   //气泡颜色

            int temp_width = 23;  //表情的宽
            int temp_height = 23; //表情的高

            int nex_w = temp_width + 2*joy_HoriSpace_bubble;             //新气泡的宽
            int new_h = temp_height + 2*joy_VertSpace_bubble;            //新气泡的高
            int new_x = curr_Width - head_HoriSpace_window - head_wh - head_HoriSpace_bubble - nex_w;   //新气泡的x坐标
            int new_y = bubble_Vert_window;                                     //新气泡的y坐标

            //新气泡矩形:   在文本矩形的基础上,画一个更大的矩形,就是气泡
            QRect NewRect = QRect(QPoint(new_x,new_y),QSize(nex_w,new_h));

            //绘制圆角矩形
            painter.drawRoundedRect(NewRect,4,4);

            //表情
            painter.drawPixmap(QRect(NewRect.x()+joy_HoriSpace_bubble,NewRect.y()+joy_VertSpace_bubble,
                                    temp_width,temp_height),m_joy);
        }
        //好友 左侧
        else{
            //头像  x:头像与窗口水平间距  y:头像与窗口垂直间距
            Rect_Righthead = QRect(QPoint(head_HoriSpace_window,head_VertSpace_window),QSize(head_wh,head_wh));
            painter.drawPixmap(Rect_Righthead,head_pixmap);

            //气泡  x:头像与窗口水平间距+头像宽+头像与气泡的水平间距 y:气泡与窗口垂直间距
            painter.setPen(Qt::black);
            painter.setBrush(QColor(235,235,235));  //气泡颜色

            int temp_width = 23;  //表情的宽
            int temp_height = 23; //表情的高

            int nex_w = temp_width + 2*joy_HoriSpace_bubble;             //新气泡的宽
            int new_h = temp_height + 2*joy_VertSpace_bubble;            //新气泡的高
            int new_x = head_HoriSpace_window + head_wh + head_HoriSpace_bubble;   //新气泡的x坐标
            int new_y = bubble_Vert_window;                                     //新气泡的y坐标

            //新气泡矩形:   在文本矩形的基础上,画一个更大的矩形,就是气泡
            QRect NewRect = QRect(QPoint(new_x,new_y),QSize(nex_w,new_h));

            //绘制圆角矩形
            painter.drawRoundedRect(NewRect,4,4);

            //表情
            painter.drawPixmap(QRect(NewRect.x()+joy_HoriSpace_bubble,NewRect.y()+joy_VertSpace_bubble,
                                    temp_width,temp_height),m_joy);
        }
    }
    // 新群成员加入
    else if(msg_type == 56){
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);

        // 设置画笔和画刷
        QPen pen(Qt::black);
        pen.setWidth(2);
        painter.setPen(pen);
        QBrush brush(QColor(30,144,255));
        painter.setBrush(brush);

        // 绘制文本
        QString text = QString("%1 加入群聊").arg(m_data);

        // 设置字体和颜色
        QFont font("微软雅黑",10);
        this->setFont(font);
        painter.setPen(Qt::white);

        QFontMetrics fontMetrics = this->fontMetrics(); //返回部件字体指标
        QRect tmp_rect = fontMetrics.boundingRect(text); //根据文件名返回一个矩形(返回墨迹覆盖的矩形)

        // 绘制圆角矩形
        int width = tmp_rect.width() + 20;
        int height = tmp_rect.height() + 10;
        int x = this->width()/2 - width/2;
        int y = this->height()/2 - height/2;
        int radius = 5;
        painter.drawRoundedRect(x, y, width, height, radius, radius);

        painter.drawText(QRect(x,y,width,height), Qt::AlignCenter, text);
    }
    // 群成员退出
    else if(msg_type == 57)
    {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);

        // 设置画笔和画刷
        QPen pen(Qt::black);
        pen.setWidth(2);
        painter.setPen(pen);
        QBrush brush(Qt::gray);
        painter.setBrush(brush);

        // 绘制文本
        QString text = QString("%1 退出群聊").arg(m_data);

        // 设置字体和颜色
        QFont font("微软雅黑",10);
        this->setFont(font);
        painter.setPen(Qt::white);

        QFontMetrics fontMetrics = this->fontMetrics(); //返回部件字体指标
        QRect tmp_rect = fontMetrics.boundingRect(text); //根据文件名返回一个矩形(返回墨迹覆盖的矩形)

        // 绘制圆角矩形
        int width = tmp_rect.width() + 20;
        int height = tmp_rect.height() + 10;
        int x = this->width()/2 - width/2;
        int y = this->height()/2 - height/2;
        int radius = 5;
        painter.drawRoundedRect(x, y, width, height, radius, radius);

        painter.drawText(QRect(x,y,width,height), Qt::AlignCenter, text);
    }
}

void MyListWidgetItem::resizeEvent(QResizeEvent* event){
    Q_UNUSED(event);
    this->curr_Width = this->width();
    this->curr_height = this->height();
    update();
}

bool MyListWidgetItem::eventFilter(QObject *object, QEvent *event)
{
    if (m_flag == R_FRIEND && msg_type == 52 && object == this && event->type() == QEvent::MouseButtonPress) {
        // 选择本地保存的路径
        QString filePath = QFileDialog::getSaveFileName(this, "保存文件", "../recv", "Text Files (*.txt)");

        if (!filePath.isEmpty()) {
            // 记录保存文件的本地路径
            GlobalObject::getGlobalObject()->setSaveFileLocalPath(filePath);
            // 向服务器发送群文件下载请求(获取群文件在资源路径)
            QVariantMap map;
            map["cmd"] = "download_group_file";
            map["fileID"] = fileID;

            GlobalObject::getGlobalObject()->sendRequest(map);

        } else {
            // 用户取消了操作或对话框因其他原因关闭
        }
    }
    // 对于其他事件或对象，继续正常处理
    return QObject::eventFilter(object, event);
}
